package net.ikenway.springboot.demo.Service.Implement;

import net.ikenway.springboot.demo.Dao.ProductRepository;
import net.ikenway.springboot.demo.Dao.ProductSortRepository;
import net.ikenway.springboot.demo.Model.Dto.ProductDto;
import net.ikenway.springboot.demo.Model.Entity.Product;
import net.ikenway.springboot.demo.Model.Entity.ProductSort;
import net.ikenway.springboot.demo.Service.Interface.ProductServiceIntf;
import net.ikenway.springboot.demo.Utils.MapperUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import javax.persistence.EntityExistsException;
import javax.persistence.EntityNotFoundException;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;

/**
 * @author MasterKenway <zk@ikenway.net>
 * @Description
 * @date Created Date 12/17/2020
 */
@Service
public class ProductServiceImpl implements ProductServiceIntf {
    private final ProductRepository productRepository;
    private final ProductSortRepository productSortRepository;
    private final MapperUtil mapperUtil;

    @Autowired
    public ProductServiceImpl(ProductRepository productRepository, ProductSortRepository productSortRepository, MapperUtil mapperUtil) {
        this.productRepository = productRepository;
        this.productSortRepository = productSortRepository;
        this.mapperUtil = mapperUtil;
    }

    @Override
    public List<ProductDto> findAll() {
        return mapperUtil.mapList(productRepository.findAll(), ProductDto.class);
    }

    public List<ProductDto> findAllByDeleted(Boolean deleted) {
        return mapperUtil.mapList(productRepository.findAllByDeleted(deleted), ProductDto.class);
    }

    @Override
    public List<ProductDto> findBySortName(String sortName) throws Exception {
        ProductSort productSort = productSortRepository.findBySortName(sortName);
        if (productSort == null) throw new EntityNotFoundException();
        return mapperUtil.mapList(productRepository.findAllByProductSortSortNameAndDeleted(sortName, false), ProductDto.class);
    }

    @Override
    public ProductDto create(ProductDto productDto) throws Exception {
        Product product = mapperUtil.map(productDto, Product.class);
        product.setProductSort(productSortRepository.findById(productDto.getSortId()).orElseThrow(EntityNotFoundException::new));
        if (productRepository.findProductByProductName(productDto.getProductName()) != null)
            throw new EntityExistsException();
        productRepository.save(product);
        return mapperUtil.map(product, ProductDto.class);
    }

    @Override
    public void update(ProductDto productDto) throws Exception {
        exitsOrNot(productDto.getProductId());
        ProductSort productSort = productSortRepository.findById(productDto.getSortId()).orElseThrow(EntityNotFoundException::new);
        Product product = mapperUtil.map(productDto, Product.class);
        product.setProductSort(productSort);
        productRepository.save(product);
    }

    @Override
    public void delete(List<Long> productIds) throws Exception {
        for (Long productId : productIds) {
            Product product = exitsOrNot(productId);
            product.setDeleted(true);
            productRepository.save(product);
        }
    }

    @Override
    public Product exitsOrNot(Long productId) throws EntityNotFoundException {
        return productRepository.findById(productId).orElseThrow(EntityNotFoundException::new);
    }
}
